package com.elephant.core.xcx;

import com.elephant.core.utils.Constants;
import com.elephant.core.utils.JsonUtils;
import com.elephant.core.utils.NetUtil;
import net.sf.json.JSONObject;
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: hai
 * @Date: 2019/1/21 16:23
 */
@RestController
@RequestMapping("/weChat/xcx")
public class CustomMessageController {

    private final static Logger logger = LoggerFactory.getLogger(CustomMessageController.class);
    /**
     * 回复消息URL
     */
    private static final String WX_SEND_MESSAGE_URL = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=";
    /**
     * 消息标题
     */
    private static final String TITLE = "点击添加老师助教";
    /**
     * 图文链接消息
     */
    private static final String DESCRIPTION = "点击进入，长按识别二维码";
    /**
     * 图文链接消息被点击后跳转的链接
     */
    private static final String LINKURL = "http://mmbiz.qpic.cn/mmbiz_jpg/mS4YjaxoIhBAybGWSTyplWnHPUIQomniaU5MJX9ppLAknfCiaccRB2z35mWgDKVtMYibXvgd3zr4GjABC4F4HibNFw/0";
    /**
     * 图文链接的封面
     */
    private static final String THUMB_URL = "https://cdn.tiku.zhan.com/zhantuan/applet/icon.png";

    private static final String APP_ID = "wx1a2e0a14eb91c6cf";
    private static final String APP_SECRET = "f9fff5aadf67d9c4a6010a30532973ee";
    private static final String MESSAGE_TOKEN = "123456";


    /**
     * 小程序客服开启消息推送验证接口，验证消息的确来自微信服务器
     * @param signature
     * @param timestamp
     * @param nonce
     * @param echostr
     * @return
     */
    @RequestMapping(value = "/checkMessage", method = RequestMethod.GET)
    public String checkMessage(String signature, String timestamp, String nonce, String echostr){

        try{
            logger.info("check message，signature：{}，timestamp：{}，nonce：{}，echostr：{}", signature, timestamp, nonce, echostr);
            if(StringUtils.isEmpty(signature)
                    || StringUtils.isEmpty(timestamp)
                    || StringUtils.isEmpty(nonce)
                    || StringUtils.isEmpty(echostr)){
                return "";
            }
            if(validateSignature(signature, timestamp, nonce)){
                return echostr;
            }else {
                return "";
            }
        }catch (Exception e){
            logger.error("check fail reason : " + e.getMessage(), e);
            return "";
        }
    }

    /**
     * 处理客服消息数据
     * @param request
     * @return
     */
    @RequestMapping(value = "/checkMessage", method = RequestMethod.POST)
    public String handleMessage(HttpServletRequest request){

        try{
            SessionMessage sessionMessage = JsonUtils.jsonToObject(getString(request), SessionMessage.class);
            logger.info("请求消息内容为：" + sessionMessage.toString());

            //事件类型不处理
            if(Constants.CustomMessageMsgType.MSGTYPE_EVENT.equals(sessionMessage.getMsgType())){
                return "";
            }

            Map<String,Object> map = new HashMap<>(3);
            //普通用户，openid
            map.put("touser",sessionMessage.getFromUserName());
            //消息类型
            map.put("msgtype","link");
            Map<String,Object> link = new HashMap<>(1);
            //消息标题
            link.put("title", TITLE);
            //图文链接消息
            link.put("description", DESCRIPTION);
            //图文链接消息被点击后跳转的链接
            link.put("url", LINKURL);
            //图文链接的封面
            link.put("thumb_url", THUMB_URL);
            map.put("link",link);

            String accessToken = getAccessToken(false);
            String result = NetUtil.doPost(WX_SEND_MESSAGE_URL + accessToken, JsonUtils.objToStr(map), true);
            if(result != null){
                logger.info("回复微信客服消息第一次，result: {}", result);
                JSONObject jsonObject = JSONObject.fromObject(result);
                logger.info( "errcode: "+ jsonObject.getInt(Constants.WxResponse.CODE_KEY));
            }
            return "success";
        }catch (Exception e){
            logger.error("handle custom fail, reason : " + e.getMessage(), e);
            return null;
        }
    }

    public String getAccessToken(boolean useCache){
        String url ="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + APP_ID + "&secret=" + APP_SECRET;
        String result = NetUtil.doGet(url);
        String accessToken = (String) JSONObject.fromObject(result).get("access_token");
        return accessToken;
    }



    private String getString(HttpServletRequest request) {
        InputStream inputStream;
        String requestStr = null;
        try{
            inputStream = request.getInputStream();
            ByteArrayOutputStream result = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int length;
            while ((length = inputStream.read(buffer)) != -1) {
                result.write(buffer, 0, length);
            }
            requestStr = result.toString(StandardCharsets.UTF_8.name());
        }catch (Exception e){
            e.printStackTrace();
        }
        return requestStr;
    }


    private boolean validateSignature(String signature, String timestamp, String nonce) {
        String[] source = new String[]{MESSAGE_TOKEN, timestamp, nonce};
        Arrays.sort(source);

        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < source.length ; i++) {
            builder.append(source[i]);
        }
        String sha = sha(builder.toString());
        logger.info("程序生成的签名数据，signature：{}", sha);
        if(sha.equals(signature)){
            logger.info("--------验证成功-------------");
            return true;
        }else {
            return false;
        }
    }


    private static String sha(String decript) {
        try {
            MessageDigest digest = java.security.MessageDigest.getInstance("SHA-1");
            digest.update(decript.getBytes());
            byte[] messageDigest = digest.digest();
            // Create Hex String
            StringBuffer hexString = new StringBuffer();
            // 字节数组转换为 十六进制 数
            for (int i = 0; i < messageDigest.length; i++) {
                String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexString.append(0);
                }
                hexString.append(shaHex);
            }
            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }
}
